<template>
  <div class="hy-swiper">
    <div class="swiper" @touchstart="touchStart" @touchmove="touchMove" @touchend="touchEnd">
      <slot></slot>
    </div>
    <div class="indicator">
      <slot name="indicator">
        <!-- {类名：布尔值，类名：布尔值} -->
        <div v-for="(item, index) in sliderCount" :key="index" :class="{active:index === currentIndex-1}" class="indi-item"></div>
      </slot>
    </div>
  </div>

</template>

<script>
  export default {
    name: "Swiper",
    props: {
      interval: {
        type: Number,
        default: 3000
      },
      animDuration: {
        type: Number,
        default: 300
      },
      moveRatio: {
        type: Number,
        default: 0.25
      },
      showIndicator: {
        type: Boolean,
        default: true
      }
    },
    data() {
      return {
        swiperWidth: 0, //获取盒子宽度
        sliderCount: 0, //获取轮播图数量
        currentIndex: 1, //设置默认索引为1
        swiperStyle: {}, //图片盒子的样式对象
        isScrolling:false //防止手指滑动过快造成空白
      }
    },
    mounted(){

      setTimeout(()=>{
        this.handleDom()
        this.startTimer()
      },300)
    },
    methods: {
      startTimer(){
        // 动画开始
        this.playTimer = window.setInterval(()=>{
          this.currentIndex++
          //设置滚动过渡
          this.scrollContent(-this.currentIndex*this.swiperWidth)
        },this.interval)
      },
      // 结束动画
      stopTimer(){
        window.clearInterval(this.playTimer)
      },

      setTransform(option){
        this.swiperStyle.transform=`translateX(${option}px)`
      },

      scrollContent(option){


        //1. 开始滚动
        this.swiperStyle.transition = 'transform '+ this.animDuration + 'ms';
        this.setTransform(option)
        // 2.判断滚动位置定情况
        this.checkPosition()
        // 监听这个组件 是否过渡完成
        this.$el.addEventListener("webkitTransitionEnd",()=>{
          // 过渡完成后 将isScrolling 设置false
          this.isScrolling = false

        })

      },
      checkPosition(){
        window.setTimeout(()=>{
          this.swiperStyle.transition = 0+'ms'
          if(this.currentIndex>=this.sliderCount+1){
            this.currentIndex=1
            this.setTransform(-this.currentIndex*this.swiperWidth)
          }else if(this.currentIndex<=0){
            this.currentIndex = this.sliderCount
            this.setTransform(-this.currentIndex*this.swiperWidth)
          }

         // 向父组件发送事件
         //this.$emit('transitionEnd', this.currentIndex-1);
        },this.animDuration)

      },
      //手动
      handleDom() {

        // 注意轮播图组件 在全局获取类 则调用他的父组件不能有同名的类出现，这样会引起混乱
        // 1.获取图片对象
        let swiperEl = document.querySelector('.swiper')
        // 2.获取轮播图列表
        let sliderEls = swiperEl.getElementsByClassName('swiperItem')
        // 3.获取轮播图列表总长度
        this.sliderCount = sliderEls.length

        // 4. 判断轮播图长度是否大于1 如果是则为图片盒子添加首尾子轮播图元素
        if (this.sliderCount > 1) {
          let firstClone = sliderEls[0].cloneNode(true)
          let lastClone = sliderEls[this.sliderCount - 1].cloneNode(true)
          swiperEl.insertBefore(lastClone,sliderEls[0])
          swiperEl.appendChild(firstClone)
          //5.获取盒子宽度
          this.swiperWidth = swiperEl.offsetWidth
          this.swiperStyle = swiperEl.style
          //设置 默认展示页
          this.currentIndex = 1
          this.setTransform(-this.swiperWidth)
        }
      },
      touchStart(e){
        this.stopTimer()
        // 1.滚动的时候点滑无效
        if(this.isScrolling) return
        this.isScrolling = true


        //记录手指触屏起始位置
        this.startX = e.touches[0].clientX

      },
      touchMove(e){
        //如果isScroll为true则不能滑动

        if(!this.isScrolling) return

        //记录手指滑动的位置
        this.currentX = e.touches[0].clientX
        this.distanceX = this.currentX-this.startX
        // 注意 手指滑动产生的距离 要加上原本轮播图走过的屏数
        let moveDistance = this.distanceX+(-this.currentIndex*this.swiperWidth)
        this.setTransform(moveDistance)
      },
      touchEnd(e){

        // 获取移动的距离
        let currentMove = Math.abs(this.distanceX)
        //判断 移动的距离是否超过所占屏幕规定的百分比 并根据 this.distanceX的正负判断滑动方向
        if(this.distanceX == 0){
          // 如果滑动的距离不超过规定阀值 则返回
          return
        }else if(this.distanceX<0 && currentMove>this.swiperWidth*this.moveRatio){
          this.currentIndex++
        }else if(this.distanceX>0 && currentMove>this.swiperWidth*this.moveRatio){
          this.currentIndex--
        }
        // 为位移过程添加滑动效果
        this.scrollContent(-this.currentIndex*this.swiperWidth)

        // 手指离开时开始定时器
        this.startTimer(this.playTimer)
        // 清空触屏后的位置信息 免得叠加
        this.currentX = 0
        this.startX=0
        this.distanceX=0

      }

    }
  }
</script>

<style>
  .hy-swiper {
    overflow: hidden;
    position:relative;
  }

  .swiper {
    display: flex;
  }
  .indicator{
    position:absolute;
    bottom:8px;
    display:flex;
    justify-content:center;
    width:100%;
  }
  .indi-item{
    box-sizing:border-box;
    width:8px;
    height:8px;
    border-radius:4px;
    background-color:#fff;
    line-height: 8px;
    text-align:center;
    margin:0 5px;
  }
  .indi-item.active{
    background-color: rgba(212,62,46,1.0);
  }
</style>
